/*!
 @header   NSArray 分类
 @abstract 对NSArray类的扩展
 @author zhuluran
 @version 1.0 2015/06/17 Create
 */

#import <Foundation/Foundation.h>

@interface NSArray (Extension)

/*!
 @method
 @abstract 返回数组中一个随机样本，或者nil
 @discussion 返回数组中一个随机样本，或者nil
  
 @return 数组中一个随机样本，或者nil
 */
- (id)sample;

/*!
 @method
 @abstract 遍历数组
 @discussion 通过enumerateObjectsUsingBlock遍历数组
 
 @param block 回调数组中每个对象
 */
- (void)each:(void (^)(id object))block;

/*!
 @method
 @abstract 遍历数组
 @discussion 通过enumerateObjectsUsingBlock遍历数组,回调值中含有index
 
 @param block 回调数组中每个对象及其index
 */
- (void)eachWithIndex:(void (^)(id object, NSUInteger index))block;

/*!
 @method
 @abstract 根据传入范围截取子数组
 @discussion 根据传入范围截取子数组
 
 @param key 根据传入不同类型判读需要的范围 例如@"1...3"取得范围为从 1 到 2, @"1..3"取得范围为从 1 到 3 , 当传入的形式为NSValue例如(@"1,3"),则将1，3分别作为range的location和length传入用以截取子数组
 
 @return 截取到的子数组
 */
- (id)objectForKeyedSubscript:(id <NSCopying>)key;

/*!
 @method
 @abstract 判断数组是否包含某个对象
 @discussion 判断数组是否包含某个对象

 @param object 用来判断的对象
 
 @return
 */
- (BOOL)includes:(id)object;

/*!
 @method
 @abstract 从数组中取出指定个数对象
 @discussion 从数组中取出指定个数对象
 
 @param numberOfElements 需要取出的数量，当这个值大于数组所拥有的对象的数量，返回这个数组
 
 @return 指定个数的对象组成的新的数组
 */
- (NSArray *)take:(NSUInteger)numberOfElements;

/*!
 @method
 @abstract 从数组中取出对象组成新的数组
 @discussion 每个对象将放入block中检查，当return为YES时操作执行，当return为NO的时候选取过程中止
 
 @param block 放入对象用以判断是否需要继续执行
 
 @return 取得的数组
 */
- (NSArray *)takeWhile:(BOOL (^)(id object))block;

/*!
 @method
 @abstract 数组遍历修改
 @discussion 将数组中所有元素遍历传入block，在block中修改后的对象构成新的数组返回

 @param block 遍历对象用于依次修改
 
 @return 修改后的新的数组
 */
- (NSArray *)map:(id (^)(id object))block;

/*!
 @method
 @abstract 选择数组中的对象是否需要保留，结果构成新的数组
 @discussion 选择数组中的对象是否需要保留，结果构成新的数组

 @param block 依次遍历对象判断是否需要保留
 
 @return 所有需要保留的对象构成的新的数组
 */
- (NSArray *)select:(BOOL (^)(id object))block;

/*!
 @method
 @abstract 查找某个对象
 @discussion 无序遍历数组，将对象放入block中用以按条件判断是否找到，返回第一个满足条件的对象
 
 @param block 传入对象用以判断是否是需要查找的那个
 
 @return 第一个找到的对象
 */
- (id)detect:(BOOL (^)(id object))block;

/*!
 @method
 @abstract 数组移除部分对象
 @discussion block中依次判断对象是否需要移除，返回移除部分对象后的数组
 
 @param block 判断是否需要移除
 
 @return 移除部分对象后的数组
 */
- (NSArray *)reject:(BOOL (^)(id object))block;

/*!
 @method
 @abstract 将一个数组中的多个数组中的对象合并成一个数组并返回
 @discussion 将一个数组中的多个数组中的对象合并成一个数组并返回

 @return 多个数组中的对象合并后的数组
 */
- (NSArray *)flatten;

/*!
 @method
 @abstract 合并数组中的NSString
 @discussion 将一个数组中的NSString合并在一起并返回

 @return 合并后的NSString
 */
- (NSString *)join;

/*!
 @method
 @abstract 合并数组中的NSString,用separator隔开
 @discussion 将一个数组中的NSString用separator隔开,合并在一起并返回

 @param separator 分隔字符
 
 @return 合并后的NSString
 */
- (NSString *)join:(NSString *)separator;

/*!
 @method
 @abstract 数组排序
 @discussion 通过默认的排序方式将数组排序后返回

 @return 排序后的数组
 */
- (NSArray *)sort;

/*!
 @method
 @abstract 数组通过关键字排序
 @discussion 将数组中的对象的关键字进行排序后返回
 
 @param key 需要排序的对象的关键字
 
 @return 排序后的数组
 */
- (NSArray *)sortBy:(NSString*)key;

/*!
 @method
 @abstract 数组逆序
 @discussion 将数组中的对象逆序排列后返回

 @return 逆序后的数组
 */
- (NSArray *)reverse;

/*!
 @method
 @abstract 求两个集合的交集
 @discussion 返回两个集合的交集
             交集：同时存在在两个集合中的对象构成的集合
 @param array 求交集的集合
 
 @return 两个集合的交集
 */
- (NSArray *)intersectionWithArray:(NSArray *)array;

/*!
 @method
 @abstract 求两个集合的并集
 @discussion 返回两个集合的并集
             并集：在集合A中或者集合B中存在的对象构成的集合
 @param array 求并集的集合
 
 @return 两个集合的并集
 */
- (NSArray *)unionWithArray:(NSArray *)array;

/*!
 @method
 @abstract 求两个集合的补集
 @discussion 返回两个集合的补集（self - array）
             补集：将集合A中的对象，去掉同时存在于集合AB中的对象所构成的集合
 @param array 求补集的集合
 
 @return 补集
 */
- (NSArray *)relativeComplement:(NSArray *)array;

/*!
 @method
 @abstract 求两个集合的补集的并集
 @discussion 返回两个集合的补集的并集
             两个集合的补集的并集：两个集合的所有对象中，去掉同时出现于两个集合的对象后剩下的对象所构成的集合
 @param array 求补集的并集的另一个集合
 
 @return 两个集合的补集的并集
 */
- (NSArray *)symmetricDifference:(NSArray *)array;
@end
